// xhash internal header
#ifndef _XHASH_
#define _XHASH_
#include <cstring>
#include <cwchar>
#include <functional>
#include <list>
#include <vector>

#undef _HAS_STLPORT_EMULATION

 #if _HAS_TRADITIONAL_STL
 #define _HAS_STLPORT_EMULATION	1
 #endif /* _HAS_TRADITIONAL_STL */

_STD_BEGIN

		// TEMPLATE FUNCTION hash_value
 #define _HASH_SEED	(size_t)0xdeadbeef

template<class _Kty> inline
	size_t hash_value(const _Kty& _Keyval)
	{	// hash _Keyval to size_t value one-to-one
	return ((size_t)_Keyval ^ _HASH_SEED);
	}

 #if _IS_EMBEDDED
inline size_t _Hash_value(const char *_Begin, const char *_End)
	{	// hash range of char
	size_t _Val = 2166136261U;
	while(_Begin != _End)
		_Val = 16777619U * _Val ^ (size_t)*_Begin++;
	return (_Val);
	}

inline size_t _Hash_value(const wchar_t *_Begin, const wchar_t *_End)
	{	// hash range of wchar_t
	size_t _Val = 2166136261U;
	while(_Begin != _End)
		_Val = 16777619U * _Val ^ (size_t)*_Begin++;
	return (_Val);
	}

inline size_t hash_value(const string& _Str)
	{	// hash string to size_t value
	return (_Hash_value(_Str.begin(), _Str.end()));
	}

 #else /* _IS_EMBEDDED */
template <class _Init>
	inline size_t _Hash_value(_Init _Begin, _Init _End)
	{	// hash range of elements
	size_t _Val = 2166136261U;
	while(_Begin != _End)
		_Val = 16777619U * _Val ^ (size_t)*_Begin++;
	return (_Val);
	}

template<class _Elem,
	class _Traits,
	class _Alloc> inline
	size_t hash_value(const basic_string<_Elem, _Traits, _Alloc>& _Str)
	{	// hash string to size_t value
	return (_Hash_value(_Str.begin(), _Str.end()));
	}
 #endif /* _IS_EMBEDDED */

inline size_t hash_value(const char *_Str)
	{	// hash NTBS to size_t value
	return (_Hash_value(_Str, _Str + _CSTD strlen(_Str)));
	}

inline size_t hash_value(const wchar_t *_Str)
	{	// hash NTWCS to size_t value
	return (_Hash_value(_Str, _Str + _CSTD wcslen(_Str)));
	}

		// TEMPLATE CLASS hash_compare
template<class _Kty,
	class _Pr = less<_Kty> >
	class hash_compare
	{	// traits class for hash containers
public:
	enum
		{	// parameters for hash table
		bucket_size = 4,	// 0 < bucket_size
		min_buckets = 8};	// min_buckets = 2 ^^ N, 0 < N

	hash_compare()
		: comp()
		{	// construct with default comparator
		}

	hash_compare(_Pr _Pred)
		: comp(_Pred)
		{	// construct with _Pred comparator
		}

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		ldiv_t _Qrem = ldiv((size_t)_Keyval, 127773);
		_Qrem.rem = 16807 * _Qrem.rem - 2836 * _Qrem.quot;
		if (_Qrem.rem < 0)
			_Qrem.rem += 2147483647;
		return ((size_t)_Qrem.rem);
		}

	bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
		{	// test if _Keyval1 ordered before _Keyval2
		return (comp(_Keyval1, _Keyval2));
		}

protected:
	_Pr comp;	// the comparator object
	};

 #if _HAS_TRADITIONAL_STL
		// TEMPLATE CLASS hash for STLport
template<class _Kty>
	class hash
	{	// traits class for hash function
public:
	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value by pseudorandomizing transform
		ldiv_t _Qrem = ldiv((size_t)_Keyval, 127773);
		_Qrem.rem = 16807 * _Qrem.rem - 2836 * _Qrem.quot;
		if (_Qrem.rem < 0)
			_Qrem.rem += 2147483647;
		return ((size_t)_Qrem.rem);
		}
	};

		// TEMPLATE CLASS _Hash_compare for STLport
template<class _Kty,
	class _Hasher,
	class _Keyeq>
	class _Hash_compare
	{	// traits class for hash containers
public:
	typedef _Hasher hasher;
	enum
		{	// parameters for hash table
		bucket_size = 4,	// 0 < bucket_size
		min_buckets = 8};	// min_buckets = 2 ^^ N, 0 < N

	_Hash_compare()
		{	// construct with default hasher and equality comparator
		}

	_Hash_compare(hasher _Hasharg)
		: _Hashobj(_Hasharg)
		{	// construct with hasher and default equality comparator
		}

	_Hash_compare(hasher _Hasharg, _Keyeq _Keyeqarg)
		: _Hashobj(_Hasharg), _Keyeqobj(_Keyeqarg)
		{	// construct with hasher and equality comparator
		}

	size_t operator()(const _Kty& _Keyval) const
		{	// hash _Keyval to size_t value
		return ((size_t)_Hashobj(_Keyval));
		}

	bool operator()(const _Kty& _Keyval1, const _Kty& _Keyval2) const
		{	// test if _Keyval1 NOT equal to _Keyval2
		return (!_Keyeqobj(_Keyval1, _Keyval2));
		}

	hasher _Hashobj;	// the hash object
	_Keyeq _Keyeqobj;	// the equality comparator object
	};
 #endif /* _HAS_TRADITIONAL_STL */

		// TEMPLATE CLASS _Hash
template<class _Traits>
	class _Hash
		: public _Traits	// traits serves as base class
	{	// hash table -- list with vector of iterators for quick access
public:
	typedef _Hash<_Traits> _Myt;
	typedef typename _Traits::key_type key_type;
	typedef typename _Traits::key_compare key_compare;
	typedef typename _Traits::value_compare value_compare;
	enum
		{	// hoist constants from key_compare
		bucket_size = key_compare::bucket_size,
		min_buckets = key_compare::min_buckets,
		_Multi = _Traits::_Multi};
	typedef list<typename _Traits::value_type,
		typename _Traits::allocator_type> _Mylist;

	typedef typename _Mylist::allocator_type allocator_type;
	typedef typename _Mylist::size_type size_type;
	typedef typename _Mylist::difference_type difference_type;
	typedef typename _Mylist::pointer pointer;
	typedef typename _Mylist::const_pointer const_pointer;
	typedef typename _Mylist::reference reference;
	typedef typename _Mylist::const_reference const_reference;

 #if _HAS_IMMUTABLE_SETS
	typedef typename _Mylist::iterator _Myiterator;
	typedef typename _Traits::_ITptr _ITptr;
	typedef typename _Traits::_IReft _IReft;

		// CLASS iterator
	class iterator
		: public _Myiterator
		{	// possibly non-mutable iterator
	public:
		typedef _ITptr pointer;
		typedef _IReft reference;

		iterator()
			{	// construct default iterator
			}

		iterator(const _Myiterator& _Iter)
			: _Myiterator(_Iter)
			{	// construct from _Myiterator
			}

		_IReft operator*() const
			{	// change to const_reference
			return ((_IReft)**(_Myiterator *)this);
			}

		_ITptr operator->() const
			{	// change to const_pointer
			return ((_ITptr)&**(_Myiterator *)this);
			}
		};

 #else /* _HAS_IMMUTABLE_SETS */
	typedef typename _Mylist::iterator iterator;
 #endif /* _HAS_IMMUTABLE_SETS */

	typedef typename _Mylist::const_iterator const_iterator;
	typedef typename _Mylist::reverse_iterator
		reverse_iterator;
	typedef typename _Mylist::const_reverse_iterator
		const_reverse_iterator;
	typedef typename _Mylist::value_type value_type;

	typedef vector<iterator,
		typename allocator_type::template
			rebind<iterator>::other> _Myvec;
	typedef pair<iterator, bool> _Pairib;
	typedef pair<iterator, iterator> _Pairii;
	typedef pair<const_iterator, const_iterator> _Paircc;

	explicit _Hash(const key_compare& _Parg,
		const allocator_type& _Al)
		: _Traits(_Parg), _List(_Al),
			_Vec(min_buckets + 1, end(), _Al),
			_Mask(1), _Maxidx(1)
		{	// construct empty hash table
		}

	_Hash(const value_type *_First, const value_type *_Last,
		const key_compare& _Parg, const allocator_type& _Al)
		: _Traits(_Parg), _List(_Al),
			_Vec(min_buckets + 1, end(), _Al),
			_Mask(1), _Maxidx(1)
		{	// construct hash table from [_First, _Last) array
		insert(_First, _Last);
		}

	_Hash(const _Myt& _Right)
		: _Traits(_Right.comp), _List(_Right.get_allocator()),
			_Vec(_Right.get_allocator())
		{	// construct hash table by copying right
		_Copy(_Right);
		}

	~_Hash()
		{	// destroy hash table
		}

	_Myt& operator=(const _Myt& _Right)
		{	// replace contents from _Right
		if (this != &_Right)
			_Copy(_Right);
		return (*this);
		}

	iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (_List.begin());
		}

	const_iterator begin() const
		{	// return iterator for beginning of nonmutable sequence
		return (_List.begin());
		}

	iterator end()
		{	// return iterator for end of mutable sequence
		return (_List.end());
		}

	const_iterator end() const
		{	// return iterator for end of nonmutable sequence
		return (_List.end());
		}

	reverse_iterator rbegin()
		{	// return iterator for beginning of reversed mutable sequence
		return (_List.rbegin());
		}

	const_reverse_iterator rbegin() const
		{	// return iterator for beginning of reversed nonmutable sequence
		return (_List.rbegin());
		}

	reverse_iterator rend()
		{	// return iterator for end of reversed mutable sequence
		return (_List.rend());
		}

	const_reverse_iterator rend() const
		{	// return iterator for end of reversed nonmutable sequence
		return (_List.rend());
		}

	size_type size() const
		{	// return length of sequence
		return (_List.size());
		}

	size_type max_size() const
		{	// return maximum possible length of sequence
		return (_List.max_size());
		}

	bool empty() const
		{	// return true only if sequence is empty
		return (_List.empty());
		}

	allocator_type get_allocator() const
		{	// return allocator object for values
		return (_List.get_allocator());
		}

	key_compare key_comp() const
		{	// return object for comparing keys
		return (this->comp);
		}

	value_compare value_comp() const
		{	// return object for comparing values
		return (value_compare(key_comp()));
		}

	_Pairib insert(const value_type& _Val)
		{	// try to insert node with value _Val
		iterator _Plist, _Where;
		if (_Maxidx <= size() / bucket_size)
			{	// too dense, need to grow hash table
			if (_Vec.size() - 1 <= _Maxidx)
				{	// table full, double its size
				_Mask = ((_Vec.size() - 1) << 1) - 1;
				_Vec.resize(_Mask + 2, end());
				}
			else if (_Mask < _Maxidx)
				_Mask = (_Mask << 1) + 1;

			size_type _Bucket = _Maxidx - (_Mask >> 1) - 1;
			for (_Plist = _Vec[_Bucket]; _Plist != _Vec[_Bucket + 1]; )
				{	// split old bucket
				size_type _Newbucket =
					this->comp(this->_Kfn(*_Plist)) & _Mask;
				if (_Newbucket == _Bucket)
					++_Plist;	// leave element in old bucket

 #if _HAS_ITERATOR_DEBUGGING
				else if (_Newbucket != _Maxidx)
					_DEBUG_ERROR("bad hash function");
 #endif /* _HAS_ITERATOR_DEBUGGING */

				else
					{	// move element to new bucket
					size_type _Idx;
					iterator _Pnext = _Plist;
					if (++_Pnext != end())
						{	// not at end, move it
						for (_Idx = _Bucket; _Plist == _Vec[_Idx]; --_Idx)
							{	// update end iterators if moving first
							_Vec[_Idx] = _Pnext;
							if (_Idx == 0)
								break;
							}
						_List._Splice(end(), _List, _Plist, _Pnext, 0);
						_Plist = --end();
						_Vec[_Maxidx + 1] = end();
						}

					for (_Idx = _Maxidx; _Bucket < _Idx; --_Idx)
						{	// update end iterators if new bucket filled
						if (_Vec[_Idx] != end())
							break;
						_Vec[_Idx] = _Plist;
						}

					if (_Pnext == end())
						break;
					else
						_Plist = _Pnext;
					}
				}
			++_Maxidx;	// open new bucket for hash lookup
			}

		size_type _Bucket = _Hashval(this->_Kfn(_Val));
		for (_Plist = _Vec[_Bucket + 1]; _Plist != _Vec[_Bucket]; )
			if (this->comp(this->_Kfn(_Val), this->_Kfn(*--_Plist)))
				;	// still too high in bucket list
			else if (this->comp(this->_Kfn(*_Plist), this->_Kfn(_Val)))
				{	// found insertion point, back up to it
				++_Plist;
				break;
				}
			else if (_Multi)
				break;	// equivalent, insert only if multi
			else
				return (_Pairib(_Plist, false));	// already present

		_Where = _List.insert(_Plist, _Val);	// insert new element
		for (; _Plist == _Vec[_Bucket]; --_Bucket)
			{	// update end iterators if new first bucket element
			_Vec[_Bucket] = _Where;
			if (_Bucket == 0)
				break;
			}

		return (_Pairib(_Where, true));	// return iterator for new element
		}

	iterator insert(iterator, const value_type& _Val)
		{	// try to insert node with value _Val, ignore hint
		return (insert(_Val).first);
		}

	template<class _Iter>
		void insert(_Iter _First, _Iter _Last)
		{	// insert [_First, _Last) one at a time

 #if _HAS_ITERATOR_DEBUGGING
		_DEBUG_RANGE(_First, _Last);
		if (_Debug_get_cont(_First) == this)
			_DEBUG_ERROR("hash_map/set insertion overlaps range");
 #endif /* _HAS_ITERATOR_DEBUGGING */

		for (; _First != _Last; ++_First)
			insert(*_First);
		}

	iterator erase(iterator _Where)
		{	// erase element at _Where
		size_type _Bucket = _Hashval(this->_Kfn(*_Where));
		for (; _Where == _Vec[_Bucket]; --_Bucket)
			{	// update end iterators if erasing first
			++_Vec[_Bucket];
			if (_Bucket == 0)
				break;
			}
		return (_List.erase(_Where));
		}

	iterator erase(iterator _First, iterator _Last)
		{	// erase [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		if (_First == begin() && _Last == end())
			{	// erase all
			clear();
			return (begin());
			}
		else
			{	// partial erase, one at a time
			while (_First != _Last)
				erase(_First++);
			return (_First);
			}
		}

	size_type erase(const key_type& _Keyval)
		{	// erase and count all that match _Keyval
		_Pairii _Where = equal_range(_Keyval);
		size_type _Num = 0;
		_Distance(_Where.first, _Where.second, _Num);
		erase(_Where.first, _Where.second);
		return (_Num);
		}

	void erase(const key_type *_First,
		const key_type *_Last)
		{	// erase all that match array of keys [_First, _Last)
		_DEBUG_RANGE(_First, _Last);
		for (; _First != _Last; ++_First)
			erase(*_First);
		}

	void clear()
		{	// erase all
		_List.clear();
		_Vec.assign(min_buckets + 1, end());
		_Mask = 1;
		_Maxidx = 1;
		}

	iterator find(const key_type& _Keyval)
		{	// find an element in mutable hash table that matches _Keyval
		return (lower_bound(_Keyval));
		}

	const_iterator find(const key_type& _Keyval) const
		{	// find an element in nonmutable hash table that matches _Keyval
		return (lower_bound(_Keyval));
		}

	size_type count(const key_type& _Keyval) const
		{	// count all elements that match _Keyval
		_Paircc _Ans = equal_range(_Keyval);
		size_type _Num = 0;
		_Distance(_Ans.first, _Ans.second, _Num);
		return (_Num);
		}

	iterator lower_bound(const key_type& _Keyval)
		{	// find leftmost not less than _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		iterator _Where;
		for (_Where = _Vec[_Bucket]; _Where != _Vec[_Bucket + 1]; ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				return (this->comp(_Keyval,
					this->_Kfn(*_Where)) ? end() : _Where);
		return (end());
		}

	const_iterator lower_bound(const key_type& _Keyval) const
		{	// find leftmost not less than _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		const_iterator _Where;
		for (_Where = _Vec[_Bucket]; _Where != _Vec[_Bucket + 1]; ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				return (this->comp(_Keyval,
					this->_Kfn(*_Where)) ? end() : _Where);
		return (end());
		}

	iterator upper_bound(const key_type& _Keyval)
		{	// find leftmost not greater than _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		iterator _Where;
		for (_Where = _Vec[_Bucket + 1]; _Where != _Vec[_Bucket]; )
			if (!this->comp(_Keyval, this->_Kfn(*--_Where)))
				return (this->comp(this->_Kfn(*_Where),
					_Keyval) ? end() : (iterator)++_Where);
		return (end());
		}

	const_iterator upper_bound(const key_type& _Keyval) const
		{	// find leftmost not greater than _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		const_iterator _Where;
		for (_Where = _Vec[_Bucket + 1]; _Where != _Vec[_Bucket]; )
			if (!this->comp(_Keyval, this->_Kfn(*--_Where)))
				return (this->comp(this->_Kfn(*_Where),
					_Keyval) ? end() : (const_iterator)++_Where);
		return (end());
		}

	_Pairii equal_range(const key_type& _Keyval)
		{	// find range equivalent to _Keyval in mutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		iterator _First, _Where;
		for (_Where = _Vec[_Bucket]; _Where != _Vec[_Bucket + 1]; ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				{	// found _First, look for end of range
				for (_First = _Where; _Where != _Vec[_Bucket + 1]; ++_Where)
					if (this->comp(_Keyval, this->_Kfn(*_Where)))
						break;
				if (_First == _Where)
					break;
				return (_Pairii(_First, _Where));
				}
		return (_Pairii(end(), end()));
		}

	_Paircc equal_range(const key_type& _Keyval) const
		{	// find range equivalent to _Keyval in nonmutable hash table
		size_type _Bucket = _Hashval(_Keyval);
		iterator _First, _Where;
		for (_Where = _Vec[_Bucket]; _Where != _Vec[_Bucket + 1]; ++_Where)
			if (!this->comp(this->_Kfn(*_Where), _Keyval))
				{	// found _First, look for end of range
				for (_First = _Where; _Where != _Vec[_Bucket + 1]; ++_Where)
					if (this->comp(_Keyval, this->_Kfn(*_Where)))
						break;
				if (_First == _Where)
					break;
				return (_Paircc(_First, _Where));
				}
		return (_Paircc(end(), end()));
		}

	void swap(_Myt& _Right)

 #if _HAS_ITERATOR_DEBUGGING
		{	// exchange contents with _Right
		_Myt _Tmp = *this; *this = _Right, _Right = _Tmp;
		}

 #else /* _HAS_ITERATOR_DEBUGGING */
		{	// exchange contents with _Right
		if (get_allocator() == _Right.get_allocator())
			{	// same allocator, swap control information
			_List.swap(_Right._List);
			_STD swap(_Vec, _Right._Vec);
			_STD swap(_Mask, _Right._Mask);
			_STD swap(_Maxidx, _Right._Maxidx);
			_STD swap(this->comp, _Right.comp);
			}
		else
			{	// different allocator, do multiple assigns
			_Myt _Tmp = *this; *this = _Right, _Right = _Tmp;
			}
		}
 #endif /* _HAS_ITERATOR_DEBUGGING */

 #if _HAS_TRADITIONAL_STL
size_type bucket_count() const
	{	// return number of active buckets
	return (_Maxidx);
	}

size_type max_bucket_count() const
	{	// return maximum number of buckets
	return (_Vec.size() - 1);
	}

size_type elems_in_bucket(size_type _Bucket) const
	{	// return number of elements in bucket
	size_type _Ans = 0;
	if (_Bucket < _Maxidx)
		for (iterator _Plist = _Vec[_Bucket];
			_Plist != _Vec[_Bucket + 1]; ++_Plist)
			++_Ans;
	return (_Ans);
	}
 #endif /* _HAS_TRADITIONAL_STL */

protected:
	void _Copy(const _Myt& _Right)
		{	// copy entire hash table
		_Vec.resize(_Right._Vec.size(), end());
		_Mask = _Right._Mask;
		_Maxidx = _Right._Maxidx;
		_List.clear();

		_TRY_BEGIN
		_List.insert(end(), _Right._List.begin(), _Right._List.end());
		this->comp = _Right.comp;
		_CATCH_ALL
		_List.clear();	// list or compare copy failed, bail out
		fill(_Vec.begin(), _Vec.end(), end());
		_RERAISE;
		_CATCH_END

		iterator _Whereto = begin();
		const_iterator _Wherefrom = _Right.begin();
		for (size_type _Bucket = 0; _Bucket < _Vec.size(); )
			if (_Wherefrom == _Right._Vec[_Bucket])
				_Vec[_Bucket] = _Whereto, ++_Bucket;
			else
				++_Whereto, ++_Wherefrom;
		}

	size_type _Hashval(const key_type& _Keyval) const
		{	// return hash value, masked and wrapped to current table size
		size_type _Num = this->comp(_Keyval) & _Mask;
		if (_Maxidx <= _Num)
			_Num -= (_Mask >> 1) + 1;
		return (_Num);
		}

	_Mylist _List;	// the list of elements, must initialize before _Vec
	_Myvec _Vec;	// the vector of list iterators
	size_type _Mask;	// the key mask
	size_type _Maxidx;	// current maximum key value
	};

		// _Hash TEMPLATE OPERATORS
template<class _Ty> inline
	bool operator==(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test for hash table equality
	return (_Left.size() == _Right.size()
		&& equal(_Left.begin(), _Left.end(), _Right.begin()));
	}

template<class _Ty> inline
	bool operator!=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test for hash table inequality
	return (!(_Left == _Right));
	}

template<class _Ty> inline
	bool operator<(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left < _Right for hash tables
	return (lexicographical_compare(_Left.begin(), _Left.end(),
		_Right.begin(), _Right.end()));
	}

template<class _Ty> inline
	bool operator>(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left > _Right for hash tables
	return (_Right < _Left);
	}

template<class _Ty> inline
	bool operator<=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left <= _Right for hash tables
	return (!(_Right < _Left));
	}

template<class _Ty> inline
	bool operator>=(const _Hash<_Ty>& _Left, const _Hash<_Ty>& _Right)
	{	// test if _Left >= _Right for hash tables
	return (!(_Left < _Right));
	}
_STD_END

 #if _HAS_HASH_STATISTICS
  #include <cmath>
  #include <cstdio>

template <class _Hashtab>
	void _Stats(_Hashtab _Tab)
	{	// display element distribution statistics
	unsigned long _Max = 0;
	unsigned long _Min = (size_t)(-1);
	unsigned long _Buckets = _Tab.bucket_count();
	double _Avg = _Buckets ? (double)_Tab.size() / _Buckets : 0;
	double _Var = 0;

	for (size_t _Idx = 0; _Idx != _Buckets; ++_Idx)
		{	// gather bucket data
		unsigned long _Elts = _Tab.elems_in_bucket(_Idx);
		_Var += ((double)_Elts - _Avg) * ((double)_Elts - _Avg);
		if (_Elts < _Min)
			_Min = _Elts;
		if (_Max < _Elts)
			_Max = _Elts;
		}
	_CSTD printf("elements: %ul, buckets: %ul\n", _Tab.size(), _Buckets);
	_CSTD printf("elements/bucket: %0.2f, variance: %0.2f\n",
		_Avg, _CSTD sqrt(_Var / (_Buckets + 1)));
	_CSTD printf("smallest: %u, largest: %u\n", _Min, _Max);
	}
 #endif /* _HAS_HASH_STATISTICS */

#endif /* _XHASH_ */

/*
 * Copyright (c) 1992-2003 by P.J. Plauger.  ALL RIGHTS RESERVED.
 * Consult your license regarding permissions and restrictions.
V4.02:1422 */
